/******************** (C) COPYRIGHT 2016 KSGIANTLUS ********************
* File Name          : lcd1602.c
* Author             : JASON
* Version            : V1.1
* Date               : 2016.04.10
*************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "stm32f7xx.h"                  // Device header
#include "iic_current.h"
//#include "sys.h"
#include "adc_volt.h"
//#include "usart.h"
#include "ad5274_5271.h"
#include "IOConfig.h"

#define mA 1
#define uA 0

#define COMMAND_CONFIG_INDEX			0x00
#define COMMAND_SHUNT_VLOTAGE_SETTING	0x01
#define COMMAND_BUS_VOLTAGE_INDEX		0x02
#define COMMAND_POWER_INDEX				0x03
#define COMMAND_CURRENT_INDEX			0x04	//包含流经分流电阻器的经计算的电流值
#define COMMAND_CALIBRATION_INDEX		0x05
#define COMMAND_MASK_INDEX				0x06
#define COMMAND_ALERT_LIMIT_INDEX		0x07
#define COMMAND_ID_INDEX				0xFF

#define T226_GPIO 						GPIOG
#define T226SCL							GPIO_PIN_8
#define T226SDA							GPIO_PIN_11
//------------------------------------------------------------
#define T226SCL_L 	HAL_GPIO_WritePin(T226_GPIO, T226SCL,GPIO_PIN_RESET)
#define T226SCL_H 	HAL_GPIO_WritePin(T226_GPIO, T226SCL,GPIO_PIN_SET)
#define T226SDA_L	HAL_GPIO_WritePin(T226_GPIO, T226SDA,GPIO_PIN_RESET)
#define T226SDA_H 	HAL_GPIO_WritePin(T226_GPIO, T226SDA,GPIO_PIN_SET)

//#define  CURRENT_SET_START  0X60

/** @addtogroup ADC_DMA_Transfer
  * @{
  */
  /* Definition of ADCx conversions data table size */
  #define ADC_CONVERTED_DATA_BUFFER_SIZE   ((uint32_t)  32)   /* Size of array aADCxConvertedData[] */
/* ADC handle declaration */
//ADC_HandleTypeDef             AdcHandle;

u16 RDAC=0x100;			//设定VDD用
u16 RDAC_VDDIO=0x150;	//设定VDDIO用
u16 RDAC_DVDD=0x100;

void Delay(u32 nCount)
{ 
	volatile u16 i,j;
	for(j=0;j<nCount;j++)
	{
	for(i=0;i<1000;i++)
	{;}
	}
}

void delay_us_sys(u32 Nus)
{
	volatile u32 i,j;	
	for(j=0;j<Nus;j++){
		for(i=0;i<4;i++)
		{;}
	}
	
}

BYTE pucData[2];

void TWait(void)
{
    delay_us_sys(20);
}
//--------------------------------------------------------------------------------------
void T226_GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_Initure;		
	__HAL_RCC_GPIOG_CLK_ENABLE();               //开启GPI0A时钟	
	__HAL_RCC_GPIOB_CLK_ENABLE(); 	
	__HAL_RCC_GPIOC_CLK_ENABLE(); 
	
	GPIO_Initure.Pin = VCI_TC1;
	GPIO_Initure.Speed= GPIO_SPEED_HIGH;     
	GPIO_Initure.Pull =GPIO_PULLUP;
	GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;	
	HAL_GPIO_Init(VCI_TC1_ENPeriph_GPIO,&GPIO_Initure);  //继电器控制
	VCI_T_C_LOW;  //默认mA档

	GPIO_Initure.Pin = VDDIO_TC1;
	GPIO_Initure.Speed= GPIO_SPEED_HIGH;     
	GPIO_Initure.Pull =GPIO_PULLUP;
	GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;	
	HAL_GPIO_Init(VDDIO_TC1_ENPeriph_GPIO,&GPIO_Initure);  //继电器控制
	VDDIO_T_C_LOW; //默认mA档
	
	GPIO_Initure.Pin = T226SCL;
	GPIO_Initure.Speed= GPIO_SPEED_HIGH;     
	GPIO_Initure.Pull =GPIO_PULLUP;
	GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;	
	HAL_GPIO_Init(T226_GPIO,&GPIO_Initure); 	 	
	
	GPIO_Initure.Pin = T226SDA;
	GPIO_Initure.Speed= GPIO_SPEED_HIGH;     
	GPIO_Initure.Pull = GPIO_PULLUP;
	GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;	
	HAL_GPIO_Init(T226_GPIO,&GPIO_Initure); 	
}
void T226_I2CSDASetInput(void)
{	
	GPIO_InitTypeDef GPIO_Initure;	
	GPIO_Initure.Pin = T226SDA;
	GPIO_Initure.Speed= GPIO_SPEED_HIGH;     
	GPIO_Initure.Pull = GPIO_PULLUP;
	GPIO_Initure.Mode = GPIO_MODE_INPUT;	
	HAL_GPIO_Init(T226_GPIO,&GPIO_Initure); 	
} 
void T226_I2CSDASetOutput(void)
{ 	
	GPIO_InitTypeDef GPIO_Initure;	
	GPIO_Initure.Pin = T226SDA;
	GPIO_Initure.Speed= GPIO_SPEED_HIGH;     
	GPIO_Initure.Pull = GPIO_NOPULL;//iic总线有上拉电阻，无需拉高GPIO_PULLUP;
	GPIO_Initure.Mode = GPIO_MODE_OUTPUT_OD;//GPIO_MODE_OUTPUT_PP;	
	HAL_GPIO_Init(T226_GPIO,&GPIO_Initure); 
}

// Start bit of I2C waveform
void T226_I2CStart(void)
{
    //T226_I2CSDASetOutput();
    T226_I2CSDASetOutput();
    TWait();
    T226SDA_H; 
    TWait();
    T226SCL_H;
	  TWait(); 
    TWait();
    T226SDA_L; 
	  TWait();
    TWait();
    T226SCL_L; 
    TWait();
}

// Stop bit of I2C waveform
void T226_I2CStop(void)
{
    T226_I2CSDASetOutput();   //T226_I2CSDASetOutput();    
    TWait();
    T226SCL_H;
    TWait();
    T226SDA_L;
    TWait();
    T226SCL_H;
    TWait();
    TWait();
    T226SDA_H;
    TWait();
	//T226SCL_L;
}

bool T226_I2CSendByte(BYTE ucData)
{
	bool bRet;
	unsigned char i=8; 
    T226_I2CSDASetOutput();    
	do{	
		if (ucData&0x80)
			 T226SDA_H;
			 else 
			 	T226SDA_L;
		TWait();//-------------------
		T226SCL_H;
		TWait();
		ucData<<=1;
		T226SCL_L;
                if (i>1) //判断是否传递最后一位数据，若是最后一位则TSCL拉低后不用等待
		TWait();
    }while(--i);
    T226_I2CSDASetInput();	
	bRet=FALSE;
	T226SCL_H;
	TWait();
	if (HAL_GPIO_ReadPin(T226_GPIO, T226SDA))	
	bRet=TRUE;
	T226SCL_L;
	TWait();
	return bRet;
}
  

// Receive one byte form client to host
BYTE T226_I2CReciveByte(bool bAck)
{
	BYTE ucRet,i;
	T226_I2CSDASetInput();
	ucRet = 0;
	i=8;
	do
	{	T226SCL_H;
		TWait();
		ucRet<<=1;
		if(HAL_GPIO_ReadPin(T226_GPIO, T226SDA))
			ucRet++;
		T226SCL_L;
                if (i>1) //判断是否传递最后一位数据，若是最后一位则TSCL拉低后不用等待
		TWait();
	}while(--i);
    T226_I2CSDASetOutput();
	if (bAck==0)
		T226SDA_L;
	else T226SDA_H;	
	T226SCL_H;
	TWait();
	T226SCL_L;
	TWait();         
	return ucRet;
}

bool T226_I2CTest(BYTE ucDeviceAddr)
{
      bool bRet = TRUE;
//      I2CStart();
//      if(I2CSendByte(ucDeviceAddr & 0xFE) == ACK)
//        {bRet = TRUE;          
//        }
//      else
//        {
//          bRet = FALSE;
//        }
//      I2CStop();
      return bRet;
}

bool I2C1Read (u8 ucDeviceAddr, u8 unDataLength, u8 *buff)
{
	bool bRet = TRUE;
	ucDeviceAddr<<=1;
	T226_I2CStart();
	if(T226_I2CSendByte(ucDeviceAddr | 0x01) == ACK)   //READ 
	{						
		for(u16 i = 0; i < unDataLength - 1; i++)
		{  
			*buff = T226_I2CReciveByte(ACK);
			buff++;
		}
			*buff = T226_I2CReciveByte(NAK);
	}
	else
	{ bRet = FALSE;}	
	T226_I2CStop();	
	return bRet;
} 
bool I2C1Write (u8 ucDeviceAddr, u8 unDataLength,u8 *buf)
{
	bool bRet = TRUE;
	ucDeviceAddr<<=1;	
	T226_I2CStart();
	if(T226_I2CSendByte(ucDeviceAddr & 0xFE) == ACK)
	{
		for(int t=0;t<unDataLength;t++){
			T226_I2CSendByte(buf[t]);		
		}
	}
	else{bRet = FALSE;	}
	T226_I2CStop();	
	return bRet;
} 
// I2C send data fuction
bool T226_I2CSend(BYTE ucDeviceAddr, BYTE ucIndex, u16 reg)
{
    bool bRet = TRUE;
    T226_I2CStart();
    if(T226_I2CSendByte(ucDeviceAddr & 0xFE) == ACK)
    {
		if(T226_I2CSendByte(ucIndex) == ACK)
		{
				if(T226_I2CSendByte(reg>>8) == ACK)
				{
					if(T226_I2CSendByte(reg) == NAK)
					{
						bRet = FALSE;
						//break;
					}
				}
				else
				{
					bRet = FALSE;
				}
		}
		else
				{
					bRet = FALSE;
				}
    }
    else
		{
			bRet = FALSE;
		}
    T226_I2CStop();
    return bRet;
}
// I2C receive data function
bool T226_I2CReceive(BYTE ucDeviceAddr, BYTE ucIndex, u32 *regv) //
{
    bool bRet = TRUE;
    T226_I2CStart();TWait(); 
    if(T226_I2CSendByte(ucDeviceAddr & 0xFE) == ACK)
        {
			if(T226_I2CSendByte(ucIndex) == ACK)
			{
				T226_I2CStop();		 ////Optional
				TWait(); TWait(); 
				T226_I2CStart();
				TWait(); TWait(); 
				if(T226_I2CSendByte(ucDeviceAddr | 0x01) == ACK)
					{
						//for(i = 0; i < unDataLength - 1; i++)
							//{  
								*regv = T226_I2CReciveByte(ACK);
								*regv <<=8;
							//}
							    *regv |= T226_I2CReciveByte(NAK);
					}
				else
					{          bRet = FALSE;           }
			}
			else
				{           bRet = FALSE;           }
        }
    else
        {           bRet = FALSE;           }
    T226_I2CStop();
    return bRet;
}

void T226_Init(void)
{
	T226_GPIO_Init();		
	T226_intion(DeviceAddr_AVDD);
	T226_intion(DeviceAddr_ELVDD);
	T226_intion(DeviceAddr_VCI);
	T226_intion(DeviceAddr_VDDIO);	
	T226_intion(DeviceAddr_VBAT);	
	T226_intion(DeviceAddr_DVDD);	
}


u8  T226_intion(u8 addr)
{
	uint32_t regv;
	Delay(50); 	
	T226_I2CSend(addr, COMMAND_CONFIG_INDEX, 0x077f);
	T226_I2CSend(addr, COMMAND_MASK_INDEX,0x03);
	T226_I2CSend(addr, COMMAND_CALIBRATION_INDEX, 0x01f4);  
//  pucData[0] = 0x00;
//  pucData[1] = 0x00;
//  T226_I2CReceive(addr, COMMAND_CALIBRATION_INDEX, pucData, 2);
	T226_I2CReceive(addr, COMMAND_ID_INDEX, &regv);	
	//Delay(10);
	return (regv>>8);
	//return pucData[0];	
}

unsigned long Measure_IDD_once(u8 Addr)   
{
  signed short  IDD_value=0;
	u32 VSHUNT=0; 
	u32 temp=0;
	u32 tep=0;
	delay_us_sys(10); 
	T226_I2CReceive(Addr, COMMAND_SHUNT_VLOTAGE_SETTING, &VSHUNT);	
	//VSHUNT=(pucData[0]<<8)+pucData[1];   //最小0x8000	
	IDD_value=-VSHUNT;	// //因电流输入反接，故此处返回值为负值	
	if (IDD_value<0)   ////强制其转为正值
		{	 IDD_value=-IDD_value;}	 			
	IDD_value=(u16)((IDD_value)); 
	tep=IDD_value;
		
	delay_us_sys(10); 
	T226_I2CReceive(Addr, COMMAND_BUS_VOLTAGE_INDEX, &temp);	
	tep= (temp <<16)+tep;		
		
  return tep;
}


void PMU_Oled_Measure(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8* buffer,u16 LP_B7_Data,u16 HS_B7_Data)
{
	u32 tep;
	u32 adc_ch2; //adc_ch1,
	//返回VDD VDDIO AVDD ELVDD ELVSS 测量的电压 电流值
	buffer[0]	=	0x9e;
	buffer[1] = 0x05; //lock
	buffer[2] = 33; //length
	buffer[3] =	0x00;	
	
	tep=Measure_IDD_once(DeviceAddr_ELVDD);						
	buffer[5]=(u8)(tep>>24);
	buffer[4]=(u8)(tep>>16);
	buffer[7]=(u8)(tep>>8);
	buffer[6]=(u8)(tep);
	delay_ms(1);
	tep=Measure_IDD_once(DeviceAddr_AVDD);						
	buffer[9]=(u8)(tep>>24);
	buffer[8]=(u8)(tep>>16);
	buffer[11]=(u8)(tep>>8);
	buffer[10]=(u8)(tep);
	delay_ms(1);
	tep=Measure_IDD_once(DeviceAddr_VCI);						
	buffer[13]=(u8)(tep>>24);
	buffer[12]=(u8)(tep>>16);
	buffer[15]=(u8)(tep>>8);
	buffer[14]=(u8)(tep);
	delay_ms(1);
	tep=Measure_IDD_once(DeviceAddr_VDDIO);						
	buffer[17]=(u8)(tep>>24);
	buffer[16]=(u8)(tep>>16);
	buffer[19]=(u8)(tep>>8);
	buffer[18]=(u8)(tep);
	delay_ms(1);	
	tep=Measure_IDD_once(DeviceAddr_VBAT);						
	buffer[21]=(u8)(tep>>24);
	buffer[20]=(u8)(tep>>16);
	buffer[23]=(u8)(tep>>8);
	buffer[22]=(u8)(tep);
	delay_ms(1);		
	tep=Measure_IDD_once(DeviceAddr_DVDD);						
	buffer[25]=(u8)(tep>>24);
	buffer[24]=(u8)(tep>>16);
	buffer[27]=(u8)(tep>>8);
	buffer[26]=(u8)(tep);
	delay_ms(1);		
	
	adc_ch2=Get_Adc_Average(ADC_CHANNEL_2,5);//采样通道2，5次转换值取平均
	buffer[29]=(u8)(adc_ch2>>8);
	buffer[28]=(u8)(adc_ch2); //ELVSS电压
/*	
	adc_ch1=Get_Adc_Average(ADC_CHANNEL_1,20);//采样通道1，20次转换值取平均
	buffPowerR[19]=(u8)(adc_ch1>>8);
	buffPowerR[20]=(u8)(adc_ch1); ////ELVSS 电流
	*/		
	STM2PC_SSD2828(pdev,CDC_IN_EP,buffer,buffer[2]+3);
}

void PMU_Oled_mAuA_Gear(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8* buffer,u16 LP_B7_Data,u16 HS_B7_Data)
{
		buffer[0]=0x9e;
		buffer[1] = 0x05; //lock
		buffer[2] = 25; //length
	
		if(buffer[4]==0x00) //mA
		{
			VCI_T_C_LOW;  
			VDDIO_T_C_LOW;  
		}
		else if(buffer[4]==0x01) //uA
		{
			VCI_T_C_HIGH;  
			VDDIO_T_C_HIGH;  
		}
		STM2PC_SSD2828(pdev,CDC_IN_EP,buffer,buffer[2]+3); 
}

void PMU_Oled_Vci_Vddi_Trim(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8* buffer,u16 LP_B7_Data,u16 HS_B7_Data)
{
	u32 tep;
//	u32 adc_ch2; //u32 adc_ch1,
	//RDAC配置 VDDIO VDD
	u16 step=4;
	buffer[0]=0x9e;
	if((buffer[4] &0x01)==1)  //粗调
	{
		step <<=2;
	}
	//-----------------Vci operation-------------------------------
	if	(((buffer[4] &0x02)==2)&&(RDAC<1023-step))  //Down
	{
		RDAC+=step;
		VDD_AD5274_5271_Init(RDAC);
	}
	else if(((buffer[4] &0x04)==4)&&(RDAC>step))   //Up
	{
		RDAC-=step;
		VDD_AD5274_5271_Init(RDAC);
	}
	buffer[6]=(RDAC>>8)&0xFF;
	buffer[7]=RDAC&0xFF;		
	//------------------vddi operation------------------------------			
	if	(((buffer[5] &0x02)==2)&&(RDAC_VDDIO <1023-step))  //Down
	{
		RDAC_VDDIO += step;
		VDDIO_AD5274_5271_Init(RDAC_VDDIO);
	}
	else if(((buffer[5] &0x05)==4)&&(RDAC_VDDIO>step))  //Up
	{	
		RDAC_VDDIO -= step;
		VDDIO_AD5274_5271_Init(RDAC_VDDIO);
	}
	buffer[8]=(RDAC_VDDIO>>8)&0xFF;
	buffer[9]=RDAC_VDDIO&0xFF;
	//-------------------dvdd operation--------------------------------
	if(((buffer[5] &0x20) == 0x20)&&(RDAC_DVDD < 1023-step))  //Down
	{
		RDAC_DVDD+=step;
		DVDD_AD5274_5271_Init(RDAC_DVDD);		
	}
	else if(((buffer[5] &0x40)==0x40)&&(RDAC_DVDD>step))    //Up
	{
		RDAC_DVDD -= step;
		DVDD_AD5274_5271_Init(RDAC_DVDD);
	}
	buffer[10]=(RDAC_DVDD>>8)&0xFF;
	buffer[11]=RDAC_DVDD&0xFF;
	STM2PC_SSD2828(pdev,CDC_IN_EP,buffer,buffer[2]+3); 
}


u16 MeasureCurrentmA(u8 addr) {	
  
	return Measure_IDD_once(addr);//temp;	
}
u16 MeasureCurrentuA(u8 addr) {	
  
	return Measure_IDD_once(addr);//temp;	
}
u8  redbuf[256];
u8  tepbuf[256];
u8 IIC_Mutl_Write_Read(USBD_HandleTypeDef *pdev, u8 *buf,u8 unDataLength){

	unDataLength-=(3+3+2);  //扣除包头6bytes及包尾2bytes得出有效数据数量
	//USB_Rx_Buffer[4] //预留备用
	u8 iicaddr=USB_Rx_Buffer[5];
	u8 wr_flag=USB_Rx_Buffer[6]&0x80; //USB_Rx_Buffer[6]  bit[7]读写标志:1=R,0=W ;  操作的byte数量
	u8 nums=USB_Rx_Buffer[6]&0x7f; 		   //USB_Rx_Buffer[6]  bit[7]读写标志:1=R,0=W ;  操作的byte数量
	u8 acktimes=0; //统计ACK 次数
	u8 length=0;
	for(int ii=0;ii<unDataLength;) // IIC 发送计数时从USB_Rx_Buffer[5]开始，unDataLength是数据包的总长度
	{
		wr_flag=USB_Rx_Buffer[6+ii]&0x80; //USB_Rx_Buffer[6]  bit[7]读写标志:1=R,0=W ;  操作的byte数量
		nums=USB_Rx_Buffer[6+ii]&0x7f; 		   //USB_Rx_Buffer[6]  bit[7]读写标志:1=R,0=W ;  操作的byte数量
		
		if(wr_flag==0){
			for (u8 tt=0;tt<nums;tt++)
			{
				tepbuf[tt]=USB_Rx_Buffer[6+ii+1+tt];
			}
			//bool I2C1Write (u8 ucDeviceAddr, u8 unDataLength,u8 *buf);
			acktimes+=I2C1Write (iicaddr, nums,tepbuf);
			
			ii++;ii+=nums;  //写标志(含长度)+实写长度，合计占用 nums+1个位置
		}
		else
		{
			acktimes+=I2C1Read (iicaddr, USB_Rx_Buffer[6+ii+1], redbuf);
			
			for (u8 kk=0;kk<USB_Rx_Buffer[6+ii+1];kk++)
			{
				buffer[kk+4+length]=redbuf[kk];
			}
			length+= USB_Rx_Buffer[6+ii+1];
			ii+=2;  //读标志(含长度)+实读长度 合计占用2个位置
		}		
		
	}
	

	buffer[0]=0x99;						
	buffer[1]=0x89;
	buffer[2]=length+1; //length 返回有效数据长度
	buffer[3]=acktimes;  //统计ACK 次数
	STM2PC(pdev,CDC_IN_EP,buffer,buffer[2]+3); delay_ms(1);
	return i;
}

